home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / libtiff / tools / tiffdump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  19.4 KB  |  741 lines

  1. /* $Header: /usr/people/sam/tiff/tools/RCS/tiffdump.c,v 1.49 1996/03/29 16:38:33 sam Rel $ */
  2.  
  3. /*
  4.  * Copyright (c) 1988-1996 Sam Leffler
  5.  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30.  
  31. #if defined(VMS)
  32. #include <unixio.h>
  33. #include <file.h>
  34. #elif defined(_WINDOWS)
  35. #include <io.h>
  36. #define    off_t    toff_t
  37. #include "tiffio.h"
  38. #include <fcntl.h>
  39. #elif defined(applec)
  40. #define open _open_ /* to avoid conflicts */
  41. #include <fcntl.h>
  42. #undef open
  43. int  open(const char*, int, int);
  44. typedef unsigned int off_t;
  45. #else /* !VMS && !_WINDOWS && !applec */
  46. #ifdef unix
  47. #include <sys/types.h>
  48. #endif
  49. #include <unistd.h>
  50. #include <fcntl.h>
  51. #endif
  52.  
  53. #if defined(MSDOS)
  54. #include <malloc.h>
  55. #endif
  56.  
  57. #ifndef O_BINARY
  58. #define    O_BINARY    0
  59. #endif
  60.  
  61. #include "tiffio.h"
  62.  
  63. char*    appname;
  64. char*    curfile;
  65. int    swabflag;
  66. int    bigendian;
  67. int    typeshift[13];    /* data type shift counts */
  68. long    typemask[13];    /* data type masks */
  69.  
  70. char*    bytefmt = "%s%#02x";        /* BYTE */
  71. char*    sbytefmt = "%s%d";        /* SBYTE */
  72. char*    shortfmt = "%s%u";        /* SHORT */
  73. char*    sshortfmt = "%s%d";        /* SSHORT */
  74. char*    longfmt = "%s%lu";        /* LONG */
  75. char*    slongfmt = "%s%ld";        /* SLONG */
  76. char*    rationalfmt = "%s%g";        /* RATIONAL */
  77. char*    srationalfmt = "%s%g";        /* SRATIONAL */
  78. char*    floatfmt = "%s%g";        /* FLOAT */
  79. char*    doublefmt = "%s%g";        /* DOUBLE */
  80.  
  81. static    void dump(int, uint32);
  82. extern    int optind;
  83. extern    char* optarg;
  84.  
  85. void
  86. usage()
  87. {
  88.     fprintf(stderr, "usage: %s [-h] [-o offset] file.tif ...\n", appname);
  89.     exit(-1);
  90. }
  91.  
  92. int
  93. main(int argc, char* argv[])
  94. {
  95.     int one = 1, fd;
  96.     int multiplefiles = (argc > 1);
  97.     int c;
  98.     uint32 diroff = (uint32) 0;
  99.     bigendian = (*(char *)&one == 0);
  100.  
  101.     appname = argv[0];
  102.     while ((c = getopt(argc, argv, "o:h")) != -1) {
  103.         switch (c) {
  104.         case 'h':            /* print values in hex */
  105.             shortfmt = "%s%#x";
  106.             sshortfmt = "%s%#x";
  107.             longfmt = "%s%#lx";
  108.             slongfmt = "%s%#lx";
  109.             break;
  110.         case 'o':
  111.             diroff = (uint32) strtoul(optarg, NULL, 0);
  112.             break;
  113.         default:
  114.             usage();
  115.         }
  116.     }
  117.     if (optind >= argc)
  118.         usage();
  119.     for (; optind < argc; optind++) {
  120.         fd = open(argv[optind], O_RDONLY|O_BINARY, 0);
  121.         if (fd < 0) {
  122.             perror(argv[0]);
  123.             return (-1);
  124.         }
  125.         if (multiplefiles)
  126.             printf("%s:\n", argv[optind]);
  127.         curfile = argv[optind];
  128.         swabflag = 0;
  129.         dump(fd, diroff);
  130.         close(fd);
  131.     }
  132.     return (0);
  133. }
  134.  
  135. static    TIFFHeader hdr;
  136.  
  137. #define    ord(e)    ((int)e)
  138.  
  139. /*
  140.  * Initialize shift & mask tables and byte
  141.  * swapping state according to the file
  142.  * byte order.
  143.  */
  144. static void
  145. InitByteOrder(int magic)
  146. {
  147.     typemask[0] = 0;
  148.     typemask[ord(TIFF_BYTE)] = 0xff;
  149.     typemask[ord(TIFF_SBYTE)] = 0xff;
  150.     typemask[ord(TIFF_UNDEFINED)] = 0xff;
  151.     typemask[ord(TIFF_SHORT)] = 0xffff;
  152.     typemask[ord(TIFF_SSHORT)] = 0xffff;
  153.     typemask[ord(TIFF_LONG)] = 0xffffffff;
  154.     typemask[ord(TIFF_SLONG)] = 0xffffffff;
  155.     typemask[ord(TIFF_RATIONAL)] = 0xffffffff;
  156.     typemask[ord(TIFF_SRATIONAL)] = 0xffffffff;
  157.     typemask[ord(TIFF_FLOAT)] = 0xffffffff;
  158.     typemask[ord(TIFF_DOUBLE)] = 0xffffffff;
  159.     typeshift[0] = 0;
  160.     typeshift[ord(TIFF_LONG)] = 0;
  161.     typeshift[ord(TIFF_SLONG)] = 0;
  162.     typeshift[ord(TIFF_RATIONAL)] = 0;
  163.     typeshift[ord(TIFF_SRATIONAL)] = 0;
  164.     typeshift[ord(TIFF_FLOAT)] = 0;
  165.     typeshift[ord(TIFF_DOUBLE)] = 0;
  166.     if (magic == TIFF_BIGENDIAN) {
  167.         typeshift[ord(TIFF_BYTE)] = 24;
  168.         typeshift[ord(TIFF_SBYTE)] = 24;
  169.         typeshift[ord(TIFF_SHORT)] = 16;
  170.         typeshift[ord(TIFF_SSHORT)] = 16;
  171.         swabflag = !bigendian;
  172.     } else {
  173.         typeshift[ord(TIFF_BYTE)] = 0;
  174.         typeshift[ord(TIFF_SBYTE)] = 0;
  175.         typeshift[ord(TIFF_SHORT)] = 0;
  176.         typeshift[ord(TIFF_SSHORT)] = 0;
  177.         swabflag = bigendian;
  178.     }
  179. }
  180.  
  181. static    uint32 ReadDirectory(int, unsigned, uint32);
  182. static    void ReadError(char*);
  183. static    void Error(const char*, ...);
  184. static    void Fatal(const char*, ...);
  185.  
  186. static void
  187. dump(int fd, uint32 diroff)
  188. {
  189.     unsigned i;
  190.  
  191.     lseek(fd, (off_t) 0, 0);
  192.     if (read(fd, (char*) &hdr, sizeof (hdr)) != sizeof (hdr))
  193.         ReadError("TIFF header");
  194.     /*
  195.      * Setup the byte order handling.
  196.      */
  197.     if (hdr.tiff_magic != TIFF_BIGENDIAN && hdr.tiff_magic != TIFF_LITTLEENDIAN)
  198.         Fatal("Not a TIFF file, bad magic number %u (%#x)",
  199.             hdr.tiff_magic, hdr.tiff_magic);
  200.     InitByteOrder(hdr.tiff_magic);
  201.     /*
  202.      * Swap header if required.
  203.      */
  204.     if (swabflag) {
  205.         TIFFSwabShort(&hdr.tiff_version);
  206.         TIFFSwabLong(&hdr.tiff_diroff);
  207.     }
  208.     /*
  209.      * Now check version (if needed, it's been byte-swapped).
  210.      * Note that this isn't actually a version number, it's a
  211.      * magic number that doesn't change (stupid).
  212.      */
  213.     if (hdr.tiff_version != TIFF_VERSION)
  214.         Fatal("Not a TIFF file, bad version number %u (%#x)",
  215.             hdr.tiff_version, hdr.tiff_version); 
  216.     printf("Magic: %#x <%s-endian> Version: %#x\n",
  217.         hdr.tiff_magic,
  218.         hdr.tiff_magic == TIFF_BIGENDIAN ? "big" : "little",
  219.         hdr.tiff_version);
  220.     if (diroff == 0)
  221.         diroff = hdr.tiff_diroff;
  222.     for (i = 0; diroff != 0; i++) {
  223.         if (i > 0)
  224.             putchar('\n');
  225.         diroff = ReadDirectory(fd, i, diroff);
  226.     }
  227. }
  228.  
  229. static int datawidth[] = {
  230.     0,    /* nothing */
  231.     1,    /* TIFF_BYTE */
  232.     1,    /* TIFF_ASCII */
  233.     2,    /* TIFF_SHORT */
  234.     4,    /* TIFF_LONG */
  235.     8,    /* TIFF_RATIONAL */
  236.     1,    /* TIFF_SBYTE */
  237.     1,    /* TIFF_UNDEFINED */
  238.     2,    /* TIFF_SSHORT */
  239.     4,    /* TIFF_SLONG */
  240.     8,    /* TIFF_SRATIONAL */
  241.     4,    /* TIFF_FLOAT */
  242.     8,    /* TIFF_DOUBLE */
  243. };
  244. #define    NWIDTHS    (sizeof (datawidth) / sizeof (datawidth[0]))
  245. static    int TIFFFetchData(int, TIFFDirEntry*, void*);
  246. static    void PrintTag(FILE*, uint16);
  247. static    void PrintType(FILE*, uint16);
  248. static    void PrintData(FILE*, uint16, uint32, unsigned char*);
  249. static    void PrintByte(FILE*, const char*, TIFFDirEntry*);
  250. static    void PrintShort(FILE*, const char*, TIFFDirEntry*);
  251. static    void PrintLong(FILE*, const char*, TIFFDirEntry*);
  252.  
  253. /*
  254.  * Read the next TIFF directory from a file
  255.  * and convert it to the internal format.
  256.  * We read directories sequentially.
  257.  */
  258. static uint32
  259. ReadDirectory(int fd, unsigned ix, uint32 off)
  260. {
  261.     register TIFFDirEntry *dp;
  262.     register int n;
  263.     TIFFDirEntry *dir = 0;
  264.     uint16 dircount;
  265.     int space;
  266.     uint32 nextdiroff = 0;
  267.  
  268.     if (off == 0)            /* no more directories */
  269.         goto done;
  270.     if (lseek(fd, (off_t) off, 0) != off) {
  271.         Fatal("Seek error accessing TIFF directory");
  272.         goto done;
  273.     }
  274.     if (read(fd, (char*) &dircount, sizeof (uint16)) != sizeof (uint16)) {
  275.         ReadError("directory count");
  276.         goto done;
  277.     }
  278.     if (swabflag)
  279.         TIFFSwabShort(&dircount);
  280.     dir = (TIFFDirEntry *)_TIFFmalloc(dircount * sizeof (TIFFDirEntry));
  281.     if (dir == NULL) {
  282.         Fatal("No space for TIFF directory");
  283.         goto done;
  284.     }
  285.     n = read(fd, (char*) dir, dircount*sizeof (*dp));
  286.     if (n != dircount*sizeof (*dp)) {
  287.         n /= sizeof (*dp);
  288.         Error(
  289.         "Could only read %u of %u entries in directory at offset %#lx",
  290.             n, dircount, (unsigned long) off);
  291.         dircount = n;
  292.     }
  293.     if (read(fd, (char*) &nextdiroff, sizeof (uint32)) != sizeof (uint32))
  294.         nextdiroff = 0;
  295.     if (swabflag)
  296.         TIFFSwabLong(&nextdiroff);
  297.     printf("Directory %u: offset %lu (%#lx) next %lu (%#lx)\n", ix,
  298.         (unsigned long) off, (unsigned long) off,
  299.         (unsigned long) nextdiroff, (unsigned long) nextdiroff);
  300.     for (dp = dir, n = dircount; n > 0; n--, dp++) {
  301.         if (swabflag) {
  302.             TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
  303.             TIFFSwabArrayOfLong(&dp->tdir_count, 2);
  304.         }
  305.         PrintTag(stdout, dp->tdir_tag);
  306.         putchar(' ');
  307.         PrintType(stdout, dp->tdir_type);
  308.         putchar(' ');
  309.         printf("%lu<", (unsigned long) dp->tdir_count);
  310.         if (dp->tdir_type >= NWIDTHS) {
  311.             printf(">\n");
  312.             continue;
  313.         }
  314.         space = dp->tdir_count * datawidth[dp->tdir_type];
  315.         if (space <= 4) {
  316.             switch (dp->tdir_type) {
  317.             case TIFF_UNDEFINED:
  318.             case TIFF_ASCII: {
  319.                 unsigned char data[4];
  320.                 _TIFFmemcpy(data, &dp->tdir_offset, 4);
  321.                 if (swabflag)
  322.                     TIFFSwabLong((uint32*) data);
  323.                 PrintData(stdout,
  324.                     dp->tdir_type, dp->tdir_count, data);
  325.                 break;
  326.             }
  327.             case TIFF_BYTE:
  328.                 PrintByte(stdout, bytefmt, dp);
  329.                 break;
  330.             case TIFF_SBYTE:
  331.                 PrintByte(stdout, sbytefmt, dp);
  332.                 break;
  333.             case TIFF_SHORT:
  334.                 PrintShort(stdout, shortfmt, dp);
  335.                 break;
  336.             case TIFF_SSHORT:
  337.                 PrintShort(stdout, sshortfmt, dp);
  338.                 break;
  339.             case TIFF_LONG:
  340.                 PrintLong(stdout, longfmt, dp);
  341.                 break;
  342.             case TIFF_SLONG:
  343.                 PrintLong(stdout, slongfmt, dp);
  344.                 break;
  345.             }
  346.         } else {
  347.             unsigned char *data = (unsigned char *)_TIFFmalloc(space);
  348.             if (data) {
  349.                 if (TIFFFetchData(fd, dp, data))
  350.                     PrintData(stdout, dp->tdir_type,
  351.                         dp->tdir_count, data);
  352.                 _TIFFfree(data);
  353.             } else
  354.                 Error("No space for data for tag %u",
  355.                     dp->tdir_tag);
  356.         }
  357.         printf(">\n");
  358.     }
  359. done:
  360.     if (dir)
  361.         _TIFFfree((char *)dir);
  362.     return (nextdiroff);
  363. }
  364.  
  365. static    struct tagname {
  366.     uint16    tag;
  367.     char*    name;
  368. } tagnames[] = {
  369.     { TIFFTAG_SUBFILETYPE,    "SubFileType" },
  370.     { TIFFTAG_OSUBFILETYPE,    "OldSubFileType" },
  371.     { TIFFTAG_IMAGEWIDTH,    "ImageWidth" },
  372.     { TIFFTAG_IMAGELENGTH,    "ImageLength" },
  373.     { TIFFTAG_BITSPERSAMPLE,    "BitsPerSample" },
  374.     { TIFFTAG_COMPRESSION,    "Compression" },
  375.     { TIFFTAG_PHOTOMETRIC,    "Photometric" },
  376.     { TIFFTAG_THRESHHOLDING,    "Threshholding" },
  377.     { TIFFTAG_CELLWIDTH,    "CellWidth" },
  378.     { TIFFTAG_CELLLENGTH,    "CellLength" },
  379.     { TIFFTAG_FILLORDER,    "FillOrder" },
  380.     { TIFFTAG_DOCUMENTNAME,    "DocumentName" },
  381.     { TIFFTAG_IMAGEDESCRIPTION,    "ImageDescription" },
  382.     { TIFFTAG_MAKE,        "Make" },
  383.     { TIFFTAG_MODEL,        "Model" },
  384.     { TIFFTAG_STRIPOFFSETS,    "StripOffsets" },
  385.     { TIFFTAG_ORIENTATION,    "Orientation" },
  386.     { TIFFTAG_SAMPLESPERPIXEL,    "SamplesPerPixel" },
  387.     { TIFFTAG_ROWSPERSTRIP,    "RowsPerStrip" },
  388.     { TIFFTAG_STRIPBYTECOUNTS,    "StripByteCounts" },
  389.     { TIFFTAG_MINSAMPLEVALUE,    "MinSampleValue" },
  390.     { TIFFTAG_MAXSAMPLEVALUE,    "MaxSampleValue" },
  391.     { TIFFTAG_XRESOLUTION,    "XResolution" },
  392.     { TIFFTAG_YRESOLUTION,    "YResolution" },
  393.     { TIFFTAG_PLANARCONFIG,    "PlanarConfig" },
  394.     { TIFFTAG_PAGENAME,        "PageName" },
  395.     { TIFFTAG_XPOSITION,    "XPosition" },
  396.     { TIFFTAG_YPOSITION,    "YPosition" },
  397.     { TIFFTAG_FREEOFFSETS,    "FreeOffsets" },
  398.     { TIFFTAG_FREEBYTECOUNTS,    "FreeByteCounts" },
  399.     { TIFFTAG_GRAYRESPONSEUNIT,    "GrayResponseUnit" },
  400.     { TIFFTAG_GRAYRESPONSECURVE,"GrayResponseCurve" },
  401.     { TIFFTAG_GROUP3OPTIONS,    "Group3Options" },
  402.     { TIFFTAG_GROUP4OPTIONS,    "Group4Options" },
  403.     { TIFFTAG_RESOLUTIONUNIT,    "ResolutionUnit" },
  404.     { TIFFTAG_PAGENUMBER,    "PageNumber" },
  405.     { TIFFTAG_COLORRESPONSEUNIT,"ColorResponseUnit" },
  406.     { TIFFTAG_TRANSFERFUNCTION,    "TransferFunction" },
  407.     { TIFFTAG_SOFTWARE,        "Software" },
  408.     { TIFFTAG_DATETIME,        "DateTime" },
  409.     { TIFFTAG_ARTIST,        "Artist" },
  410.     { TIFFTAG_HOSTCOMPUTER,    "HostComputer" },
  411.     { TIFFTAG_PREDICTOR,    "Predictor" },
  412.     { TIFFTAG_WHITEPOINT,    "Whitepoint" },
  413.     { TIFFTAG_PRIMARYCHROMATICITIES,"PrimaryChromaticities" },
  414.     { TIFFTAG_COLORMAP,        "Colormap" },
  415.     { TIFFTAG_HALFTONEHINTS,    "HalftoneHints" },
  416.     { TIFFTAG_TILEWIDTH,    "TileWidth" },
  417.     { TIFFTAG_TILELENGTH,    "TileLength" },
  418.     { TIFFTAG_TILEOFFSETS,    "TileOffsets" },
  419.     { TIFFTAG_TILEBYTECOUNTS,    "TileByteCounts" },
  420.     { TIFFTAG_BADFAXLINES,    "BadFaxLines" },
  421.     { TIFFTAG_CLEANFAXDATA,    "CleanFaxData" },
  422.     { TIFFTAG_CONSECUTIVEBADFAXLINES, "ConsecutiveBadFaxLines" },
  423.     { TIFFTAG_SUBIFD,        "SubIFD" },
  424.     { TIFFTAG_INKSET,        "InkSet" },
  425.     { TIFFTAG_INKNAMES,        "InkNames" },
  426.     { TIFFTAG_DOTRANGE,        "DotRange" },
  427.     { TIFFTAG_TARGETPRINTER,    "TargetPrinter" },
  428.     { TIFFTAG_EXTRASAMPLES,    "ExtraSamples" },
  429.     { TIFFTAG_SAMPLEFORMAT,    "SampleFormat" },
  430.     { TIFFTAG_SMINSAMPLEVALUE,    "SMinSampleValue" },
  431.     { TIFFTAG_SMAXSAMPLEVALUE,    "SMaxSampleValue" },
  432.     { TIFFTAG_JPEGPROC,        "JPEGProcessingMode" },
  433.     { TIFFTAG_JPEGIFOFFSET,    "JPEGInterchangeFormat" },
  434.     { TIFFTAG_JPEGIFBYTECOUNT,    "JPEGInterchangeFormatLength" },
  435.     { TIFFTAG_JPEGRESTARTINTERVAL,"JPEGRestartInterval" },
  436.     { TIFFTAG_JPEGLOSSLESSPREDICTORS,"JPEGLosslessPredictors" },
  437.     { TIFFTAG_JPEGPOINTTRANSFORM,"JPEGPointTransform" },
  438.     { TIFFTAG_JPEGQTABLES,    "JPEGQTables" },
  439.     { TIFFTAG_JPEGDCTABLES,    "JPEGDCTables" },
  440.     { TIFFTAG_JPEGACTABLES,    "JPEGACTables" },
  441.     { TIFFTAG_YCBCRCOEFFICIENTS,"YCbCrCoefficients" },
  442.     { TIFFTAG_YCBCRSUBSAMPLING,    "YCbCrSubsampling" },
  443.     { TIFFTAG_YCBCRPOSITIONING,    "YCbCrPositioning" },
  444.     { TIFFTAG_REFERENCEBLACKWHITE, "ReferenceBlackWhite" },
  445.     { TIFFTAG_REFPTS,        "IgReferencePoints (Island Graphics)" },
  446.     { TIFFTAG_REGIONTACKPOINT,    "IgRegionTackPoint (Island Graphics)" },
  447.     { TIFFTAG_REGIONWARPCORNERS,"IgRegionWarpCorners (Island Graphics)" },
  448.     { TIFFTAG_REGIONAFFINE,    "IgRegionAffine (Island Graphics)" },
  449.     { TIFFTAG_MATTEING,        "OBSOLETE Matteing (Silicon Graphics)" },
  450.     { TIFFTAG_DATATYPE,        "OBSOLETE DataType (Silicon Graphics)" },
  451.     { TIFFTAG_IMAGEDEPTH,    "ImageDepth (Silicon Graphics)" },
  452.     { TIFFTAG_TILEDEPTH,    "TileDepth (Silicon Graphics)" },
  453.     { 32768,            "OLD BOGUS Matteing tag" },
  454.     { TIFFTAG_COPYRIGHT,    "Copyright" },
  455.     { TIFFTAG_JBIGOPTIONS,    "JBIG Options" },
  456. };
  457. #define    NTAGS    (sizeof (tagnames) / sizeof (tagnames[0]))
  458.  
  459. static void
  460. PrintTag(FILE* fd, uint16 tag)
  461. {
  462.     register struct tagname *tp;
  463.  
  464.     for (tp = tagnames; tp < &tagnames[NTAGS]; tp++)
  465.         if (tp->tag == tag) {
  466.             fprintf(fd, "%s (%u)", tp->name, tag);
  467.             return;
  468.         }
  469.     fprintf(fd, "%u (%#x)", tag, tag);
  470. }
  471.  
  472. static void
  473. PrintType(FILE* fd, uint16 type)
  474. {
  475.     static char *typenames[] = {
  476.         "0",
  477.         "BYTE",
  478.         "ASCII",
  479.         "SHORT",
  480.         "LONG",
  481.         "RATIONAL",
  482.         "SBYTE",
  483.         "UNDEFINED",
  484.         "SSHORT",
  485.         "SLONG",
  486.         "SRATIONAL",
  487.         "FLOAT",
  488.         "DOUBLE"
  489.     };
  490. #define    NTYPES    (sizeof (typenames) / sizeof (typenames[0]))
  491.  
  492.     if (type < NTYPES)
  493.         fprintf(fd, "%s (%u)", typenames[type], type);
  494.     else
  495.         fprintf(fd, "%u (%#x)", type, type);
  496. }
  497. #undef    NTYPES
  498.  
  499. static void
  500. PrintByte(FILE* fd, const char* fmt, TIFFDirEntry* dp)
  501. {
  502.     char* sep = "";
  503.  
  504.     if (hdr.tiff_magic != TIFF_LITTLEENDIAN) {
  505.         switch ((int)dp->tdir_count) {
  506.         case 4: fprintf(fd, fmt, sep, dp->tdir_offset&0xff);
  507.             sep = " ";
  508.         case 3: fprintf(fd, fmt, sep, (dp->tdir_offset>>8)&0xff);
  509.             sep = " ";
  510.         case 2: fprintf(fd, fmt, sep, (dp->tdir_offset>>16)&0xff);
  511.             sep = " ";
  512.         case 1: fprintf(fd, fmt, sep, dp->tdir_offset>>24);
  513.         }
  514.     } else {
  515.         switch ((int)dp->tdir_count) {
  516.         case 4: fprintf(fd, fmt, sep, dp->tdir_offset>>24);
  517.             sep = " ";
  518.         case 3: fprintf(fd, fmt, sep, (dp->tdir_offset>>16)&0xff);
  519.             sep = " ";
  520.         case 2: fprintf(fd, fmt, sep, (dp->tdir_offset>>8)&0xff);
  521.             sep = " ";
  522.         case 1: fprintf(fd, fmt, sep, dp->tdir_offset&0xff);
  523.         }
  524.     }
  525. }
  526.  
  527. static void
  528. PrintShort(FILE* fd, const char* fmt, TIFFDirEntry* dp)
  529. {
  530.     char *sep = "";
  531.  
  532.     if (hdr.tiff_magic != TIFF_LITTLEENDIAN) {
  533.         switch (dp->tdir_count) {
  534.         case 2: fprintf(fd, fmt, sep, dp->tdir_offset&0xffff);
  535.             sep = " ";
  536.         case 1: fprintf(fd, fmt, sep, dp->tdir_offset>>16);
  537.         }
  538.     } else {
  539.         switch (dp->tdir_count) {
  540.         case 2: fprintf(fd, fmt, sep, dp->tdir_offset>>16);
  541.             sep = " ";
  542.         case 1: fprintf(fd, fmt, sep, dp->tdir_offset&0xffff);
  543.         }
  544.     }
  545. }
  546.  
  547. static void
  548. PrintLong(FILE* fd, const char* fmt, TIFFDirEntry* dp)
  549. {
  550.     fprintf(fd, fmt, "", (long) dp->tdir_offset);
  551. }
  552.  
  553. #include <ctype.h>
  554.  
  555. static void
  556. PrintASCII(FILE* fd, uint32 cc, const unsigned char* cp)
  557. {
  558.     for (; cc > 0; cc--, cp++) {
  559.         const char* tp;
  560.  
  561.         if (isprint(*cp)) {
  562.             fputc(*cp, fd);
  563.             continue;
  564.         }
  565.         for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
  566.             if (*tp++ == *cp)
  567.                 break;
  568.         if (*tp)
  569.             fprintf(fd, "\\%c", *tp);
  570.         else
  571.             fprintf(fd, "\\%03o", *cp);
  572.     }
  573. }
  574.  
  575. static void
  576. PrintData(FILE* fd, uint16 type, uint32 count, unsigned char* data)
  577. {
  578.     char* sep = "";
  579.  
  580.     switch (type) {
  581.     case TIFF_BYTE:
  582.         while (count-- > 0)
  583.             fprintf(fd, bytefmt, sep, *data++), sep = " ";
  584.         break;
  585.     case TIFF_SBYTE:
  586.         while (count-- > 0)
  587.             fprintf(fd, sbytefmt, sep, *(char *)data++), sep = " ";
  588.         break;
  589.     case TIFF_UNDEFINED:
  590.         while (count-- > 0)
  591.             fprintf(fd, bytefmt, sep, *data++), sep = " ";
  592.         break;
  593.     case TIFF_ASCII:
  594.         PrintASCII(fd, count, data);
  595.         break;
  596.     case TIFF_SHORT: {
  597.         register uint16 *wp = (uint16*)data;
  598.         while (count-- > 0)
  599.             fprintf(fd, shortfmt, sep, *wp++), sep = " ";
  600.         break;
  601.     }
  602.     case TIFF_SSHORT: {
  603.         register int16 *wp = (int16*)data;
  604.         while (count-- > 0)
  605.             fprintf(fd, sshortfmt, sep, *wp++), sep = " ";
  606.         break;
  607.     }
  608.     case TIFF_LONG: {
  609.         register uint32 *lp = (uint32*)data;
  610.         while (count-- > 0) {
  611.             fprintf(fd, longfmt, sep, (unsigned long) *lp++);
  612.             sep = " ";
  613.         }
  614.         break;
  615.     }
  616.     case TIFF_SLONG: {
  617.         register int32 *lp = (int32*)data;
  618.         while (count-- > 0)
  619.             fprintf(fd, slongfmt, sep, (long) *lp++), sep = " ";
  620.         break;
  621.     }
  622.     case TIFF_RATIONAL: {
  623.         register uint32 *lp = (uint32*)data;
  624.         while (count-- > 0) {
  625.             if (lp[1] == 0)
  626.                 fprintf(fd, "%sNan (%lu/%lu)", sep,
  627.                     (unsigned long) lp[0],
  628.                     (unsigned long) lp[1]);
  629.             else
  630.                 fprintf(fd, rationalfmt, sep,
  631.                     (double)lp[0] / (double)lp[1]);
  632.             sep = " ";
  633.             lp += 2;
  634.         }
  635.         break;
  636.     }
  637.     case TIFF_SRATIONAL: {
  638.         register int32 *lp = (int32*)data;
  639.         while (count-- > 0) {
  640.             if (lp[1] == 0)
  641.                 fprintf(fd, "%sNan (%ld/%ld)", sep,
  642.                     (long) lp[0], (long) lp[1]);
  643.             else
  644.                 fprintf(fd, srationalfmt, sep,
  645.                     (double)lp[0] / (double)lp[1]);
  646.             sep = " ";
  647.             lp += 2;
  648.         }
  649.         break;
  650.     }
  651.     case TIFF_FLOAT: {
  652.         register float *fp = (float *)data;
  653.         while (count-- > 0)
  654.             fprintf(fd, floatfmt, sep, *fp++), sep = " ";
  655.         break;
  656.     }
  657.     case TIFF_DOUBLE: {
  658.         register double *dp = (double *)data;
  659.         while (count-- > 0)
  660.             fprintf(fd, doublefmt, sep, *dp++), sep = " ";
  661.         break;
  662.     }
  663.     }
  664. }
  665.  
  666. /*
  667.  * Fetch a contiguous directory item.
  668.  */
  669. static int
  670. TIFFFetchData(int fd, TIFFDirEntry* dir, void* cp)
  671. {
  672.     int cc, w;
  673.  
  674.     w = (dir->tdir_type < NWIDTHS ? datawidth[dir->tdir_type] : 0);
  675.     cc = dir->tdir_count * w;
  676.     if (lseek(fd, (off_t) dir->tdir_offset, 0) == dir->tdir_offset &&
  677.         read(fd, cp, cc) == cc) {
  678.         if (swabflag) {
  679.             switch (dir->tdir_type) {
  680.             case TIFF_SHORT:
  681.             case TIFF_SSHORT:
  682.                 TIFFSwabArrayOfShort((uint16*) cp,
  683.                     dir->tdir_count);
  684.                 break;
  685.             case TIFF_LONG:
  686.             case TIFF_SLONG:
  687.             case TIFF_FLOAT:
  688.                 TIFFSwabArrayOfLong((uint32*) cp,
  689.                     dir->tdir_count);
  690.                 break;
  691.             case TIFF_RATIONAL:
  692.                 TIFFSwabArrayOfLong((uint32*) cp,
  693.                     2*dir->tdir_count);
  694.                 break;
  695.             case TIFF_DOUBLE:
  696.                 TIFFSwabArrayOfDouble((double*) cp,
  697.                     dir->tdir_count);
  698.                 break;
  699.             }
  700.         }
  701.         return (cc);
  702.     }
  703.     Error("Error while reading data for tag %u", dir->tdir_tag);
  704.     return (0);
  705. }
  706.  
  707. static void
  708. ReadError(char* what)
  709. {
  710.     Fatal("Error while reading %s", what);
  711. }
  712.  
  713. #include <stdarg.h>
  714.  
  715. static void
  716. vError(FILE* fd, const char* fmt, va_list ap)
  717. {
  718.     fprintf(fd, "%s: ", curfile);
  719.     vfprintf(fd, fmt, ap);
  720.     fprintf(fd, ".\n");
  721. }
  722.  
  723. static void
  724. Error(const char* fmt, ...)
  725. {
  726.     va_list ap;
  727.     va_start(ap, fmt);
  728.     vError(stderr, fmt, ap);
  729.     va_end(ap);
  730. }
  731.  
  732. static void
  733. Fatal(const char* fmt, ...)
  734. {
  735.     va_list ap;
  736.     va_start(ap, fmt);
  737.     vError(stderr, fmt, ap);
  738.     va_end(ap);
  739.     exit(-1);
  740. }
  741.